home *** CD-ROM | disk | FTP | other *** search
/ HPAVC / HPAVC CD-ROM.iso / pc / ABUSESRC.ZIP / AbuseSrc / macabuse / src / net / mac / tcpip.c < prev    next >
Encoding:
C/C++ Source or Header  |  1997-05-20  |  13.9 KB  |  655 lines

  1. #include "system.h"
  2.  
  3. #ifdef __MAC__
  4. #include "GUSI.h"
  5. #endif
  6. #include "tcpip.hpp"
  7. #include "dprint.hpp"
  8. #include <ctype.h>
  9.  
  10. #ifdef __MAC__
  11. extern tcpip_protocol tcpip;
  12. #else
  13. tcpip_protocol tcpip;
  14. #endif
  15.  
  16. //#define TCPIP_DEBUG
  17.  
  18. //{{{ net logging stuff
  19. /* 
  20. FILE *log_file=NULL;
  21. extern int net_start();
  22. void net_log(char *st, void *buf, long size)
  23. {
  24.     
  25.   if (!log_file) 
  26.   {
  27.     if (net_start())
  28.       log_file=fopen("client.log","wb");
  29.     else
  30.       log_file=fopen("server.log","wb");
  31.   }
  32.  
  33.  
  34.     dprintf(log_file,"%s%d - ",st,size);
  35.     int i;
  36.     for (i=0;i<size;i++) 
  37.       if (isprint(*((unsigned char *)buf+i)))
  38.         dprintf(log_file,"%c",*((unsigned char *)buf+i));
  39.       else dprintf(log_file,"~");
  40.  
  41.     dprintf(log_file," : ");
  42.  
  43.     for (i=0;i<size;i++) 
  44.     dprintf(log_file,"%02x, ",*((unsigned char *)buf+i),*((unsigned char *)buf+i));
  45.     dprintf(log_file,"\n");
  46.     fflush(log_file);
  47.  
  48. } */
  49. //}}}
  50.  
  51. ////////////////////////////////////////////////////////////////////////
  52. //
  53. //  unix_fd methods
  54. //
  55.  
  56. int unix_fd::read(void *buf, int size, net_address **addr) 
  57. //{{{
  58. {
  59.   int tr=::read(fd,(char*)buf,size);
  60.   if (addr) *addr=NULL;
  61.   return tr;
  62. }
  63. //}}}///////////////////////////////////
  64.  
  65. int unix_fd::write(void *buf, int size, net_address *addr)
  66. //{{{
  67.   if (addr) dprintf("Cannot change address for this socket type\n");
  68.   return ::write(fd,(char*)buf,size); 
  69. }
  70. //}}}///////////////////////////////////
  71.  
  72. void unix_fd::broadcastable()
  73. //{{{
  74. {
  75.   int zz;
  76.   if (setsockopt(fd,SOL_SOCKET,SO_BROADCAST,(char *)&zz,sizeof(zz))<0)
  77.   {
  78.     dprintf("could not set socket option broadcast");
  79.     return;
  80.   }
  81. }
  82. //}}}///////////////////////////////////
  83.  
  84. ////////////////////////////////////////////////////////////////////////
  85. //
  86. //  tcpip_protocol methods
  87. //
  88.  
  89. net_address *tcpip_protocol::get_local_address()
  90. //{{{
  91. {
  92. #if 0
  93.      struct hostent *l_hn=gethostent();
  94.  
  95.     ip_address *a=new ip_address();
  96.     memset(&a->addr,0,sizeof(a->addr));
  97.     memcpy(&a->addr.sin_addr,*l_hn->h_addr_list,4);  
  98.  
  99.     return a;  
  100. #else
  101.   char my_name[100];                        // check to see if this address is 'hostname'
  102.   gethostname(my_name,100);
  103.   ip_address *ret = 0;
  104.   
  105.   if (my_name[0]<'0' || my_name[0]>'9')
  106.   {
  107.       struct hostent *l_hn=gethostbyname(my_name);
  108.       
  109.       if (l_hn)
  110.       {
  111.           ip_address *a=new ip_address();
  112.           memset(&a->addr,0,sizeof(a->addr));
  113.           memcpy(&a->addr.sin_addr,*l_hn->h_addr_list,4);  
  114.     
  115.           return a;
  116.       }
  117.       else
  118.       {
  119.           dprintf("Enter ip address:");
  120.           gets(my_name);
  121.       }
  122.     }  
  123.  
  124.   char tmp[4],*np;
  125.     sockaddr_in host;
  126.   
  127.   np = my_name;
  128.   for (int i=0; i<4; i++)
  129.   {
  130.     int num = 0;
  131.     while (*np)
  132.     {
  133.       if (*np=='.')
  134.       {
  135.         np++;
  136.         break;
  137.       }
  138.       num = num*10 + *np - '0';
  139.       np++;
  140.     }
  141.     tmp[i] = num;
  142.   }
  143.   
  144.   memset( (char*) &host,0, sizeof(host));
  145.   host.sin_family = AF_INET;
  146.   host.sin_addr.s_addr = htonl(INADDR_ANY);
  147.   memcpy(&host.sin_addr,tmp,sizeof(in_addr));
  148.   
  149.     return new ip_address(&host);
  150. #endif
  151. }
  152. //}}}///////////////////////////////////
  153.  
  154. net_address *tcpip_protocol::get_node_address(char *&server_name, 
  155.                                                                                             int def_port, int force_port)
  156. //{{{
  157. {
  158.   sockaddr_in host;
  159.  
  160.     if (server_name[0]>='0' && server_name[0]<='9')
  161.     {
  162.       char tmp[4],*np;
  163.       
  164.       np = server_name;
  165.       for (int i=0; i<4; i++)
  166.       {
  167.         int num = 0;
  168.         while (*np && *np!=':')
  169.         {
  170.           if (*np=='.')
  171.           {
  172.             np++;
  173.             break;
  174.           }
  175.           num = num*10 + *np - '0';
  176.           np++;
  177.         }
  178.         tmp[i] = num;
  179.         if (*np == ':' & !force_port)
  180.         {
  181.             int x;
  182.           if (sscanf(np+1,"%d",&x)==1)
  183.               def_port=x;
  184.           }
  185.       }
  186.       
  187.       memset( (char*) &host,0, sizeof(host));
  188.       host.sin_family = AF_INET;
  189.       host.sin_port = htons(def_port);
  190.       host.sin_addr.s_addr = htonl(INADDR_ANY);
  191.       memcpy(&host.sin_addr,tmp,sizeof(in_addr));
  192.       
  193.       return new ip_address(&host);
  194.     }
  195.     else
  196.     {
  197.       char name[256],*np;
  198.  
  199.       np=name;
  200.       while (*server_name && *server_name!=':' && *server_name!='/')
  201.         *(np++)=*(server_name)++;
  202.       *np=0;
  203.       if (*server_name==':')
  204.       {
  205.         server_name++;
  206.         char port[256],*p;
  207.         p=port;
  208.         while (*server_name && *server_name!='/')
  209.           *(p++)=*(server_name++);
  210.         *p=0;
  211.         int x;
  212.         if (!force_port)
  213.         {
  214.           if (sscanf(port,"%d",&x)==1) def_port=x;
  215.           else return 0;
  216.         }
  217.       }
  218.     
  219.       if (*server_name=='/') server_name++;
  220.     
  221.       hostent *hp=gethostbyname(name);
  222.       if (!hp)
  223.       { 
  224.         dprintf("unable to locate server named '%s'\n",name);
  225.         return 0;
  226.       }
  227.       
  228.       memset( (char*) &host,0, sizeof(host));
  229.       host.sin_family = AF_INET;
  230.       host.sin_port = htons(def_port);
  231.       host.sin_addr.s_addr = htonl(INADDR_ANY);
  232.       memcpy(&host.sin_addr,hp->h_addr,hp->h_length);
  233.     }
  234.   return new ip_address(&host);
  235. }
  236. //}}}///////////////////////////////////
  237.  
  238. net_socket *tcpip_protocol::connect_to_server(net_address *addr, net_socket::socket_type sock_type)
  239. //{{{
  240. {
  241.   if (addr->protocol_type()!=net_address::IP)
  242.   {
  243.     dprintf("Procotol type not supported in the executable\n");
  244.     return NULL;
  245.   }
  246.  
  247.   int socket_fd=socket(AF_INET,sock_type==net_socket::SOCKET_SECURE ? SOCK_STREAM : SOCK_DGRAM,0);
  248.   if (socket_fd<0) 
  249.   {
  250.     dprintf("unable to create socket (too many open files?)\n");
  251.     return 0;
  252.   }
  253.  
  254. #ifndef __MAC__
  255.   int zz;
  256.   if (setsockopt(socket_fd,SOL_SOCKET,SO_REUSEADDR,(char *)&zz,sizeof(zz))<0)
  257.   {
  258.     dprintf("could not set socket option reuseaddr");
  259.     return 0;
  260.   }
  261. #endif
  262.     
  263.   if (connect(socket_fd, (struct sockaddr *) &((ip_address *)addr)->addr, sizeof( ((ip_address *)addr)->addr ))==-1)
  264.   { 
  265.     dprintf("unable to connect\n");
  266.     close(socket_fd);
  267.     return 0;
  268.   }
  269.  
  270.   if (sock_type==net_socket::SOCKET_SECURE)
  271.     return new tcp_socket(socket_fd);
  272.   else
  273.     return new udp_socket(socket_fd);
  274. }
  275. //}}}///////////////////////////////////
  276.  
  277. net_socket *tcpip_protocol::create_listen_socket(int &port, net_socket::socket_type sock_type)
  278. //{{{
  279. {
  280.   int socket_fd=socket(AF_INET,sock_type==net_socket::SOCKET_SECURE ? SOCK_STREAM : SOCK_DGRAM,0);
  281.   if (socket_fd<0) 
  282.   {
  283.     dprintf("unable to create socket (too many open files?)\n");
  284.     return 0;
  285.   }
  286.  
  287. #ifndef __MAC__
  288.   int zz;
  289.   if (setsockopt(socket_fd,SOL_SOCKET,SO_REUSEADDR,(char *)&zz,sizeof(zz))<0)
  290.   {
  291.     dprintf("could not set socket option reuseaddr");
  292.     return 0;
  293.   }
  294. #endif
  295.  
  296.   net_socket *s;
  297.   if (sock_type==net_socket::SOCKET_SECURE)
  298.     s=new tcp_socket(socket_fd);
  299.   else s=new udp_socket(socket_fd);
  300.   if (s->listen(port)==0)
  301.   {   
  302.     delete s;
  303.     return 0;
  304.   }
  305.  
  306.   return s;
  307. }
  308. //}}}///////////////////////////////////
  309.  
  310. net_socket *tcpip_protocol::start_notify(int port, void *data, int len)
  311. //{{{
  312. {
  313.     if (responder)
  314.     {
  315.         delete responder;
  316.         delete bcast;
  317.         responder = 0;
  318.     }
  319.     
  320.     int resp_len = strlen(notify_response);
  321.   notify_len = len + resp_len + 1;
  322.   strcpy(notify_data,notify_response);
  323.     notify_data[resp_len] = '.';
  324.   memcpy(notify_data+resp_len+1,data,len);
  325.   
  326.   // create notifier socket
  327. #ifdef TCPIP_DEBUG
  328.     dprintf("Creating notifier on port %d\n",port);
  329. #endif
  330.   notifier = create_listen_socket(port, net_socket::SOCKET_FAST);
  331.   
  332.   if (notifier)
  333.   {
  334.     notifier->read_selectable();
  335.     notifier->write_unselectable();
  336.   }
  337.   else
  338.         dprintf("Couldn't start notifier\n");
  339.   
  340.   return notifier;
  341. }
  342. //}}}///////////////////////////////////
  343.  
  344. void tcpip_protocol::end_notify()
  345. //{{{
  346. {
  347.   if (notifier)
  348.     delete notifier;
  349.   notifier = 0;
  350.  
  351.   notify_len = 0;
  352. }
  353. //}}}///////////////////////////////////
  354.  
  355. int tcpip_protocol::handle_notification()
  356. //{{{
  357. {
  358.   if (!notifier)
  359.     return 0;
  360.     
  361.   if (notifier->ready_to_read())
  362.   {
  363.     char buf[513];
  364.     int len;
  365.     // got a notification request "broadcast"
  366.     ip_address *addr;
  367.  
  368. #ifdef TCPIP_DEBUG
  369.         dprintf("Notifier: ");
  370. #endif
  371.  
  372.     len = notifier->read(buf, 512, (net_address**)&addr);
  373. #ifdef TCPIP_DEBUG
  374.         if (len>0) {
  375.             buf[len] = 0;
  376.             dprintf("[%s] ",buf);
  377.         }
  378. #endif
  379.     if (addr && len>0)
  380.     {
  381.             buf[len] = 0;
  382.       if  (strcmp(buf, notify_signature)==0) {
  383.                 char s[256];
  384. #ifdef TCPIP_DEBUG
  385.                 addr->store_string(s,256);
  386.                 dprintf("responding to %s",s);
  387. #endif
  388.         // send notification data to requester
  389.         notifier->write(notify_data,notify_len,addr);
  390.             }
  391.         
  392.       delete addr;
  393.     }
  394. #ifdef TCPIP_DEBUG
  395.         dprintf("\n");
  396. #endif
  397.     return 1;
  398.   }
  399.   if (notifier->error())
  400.   {
  401.     dprintf("Error on notification socket!\n");
  402.     return 1;
  403.   }
  404.  
  405.   return 0;
  406. }
  407. //}}}///////////////////////////////////
  408.  
  409. net_address *tcpip_protocol::find_address(int port, char *name)
  410. //{{{
  411. {
  412.   // name should be a 256 byte buffer
  413.     char s[256];
  414.  
  415.     end_notify();
  416.  
  417.   if (!responder) {
  418. //#ifdef TCPIP_DEBUG
  419.         dprintf("Creating responder on port %d\n",port);
  420. //#endif
  421.     responder = create_listen_socket(port, net_socket::SOCKET_FAST);
  422.         responder->read_selectable();
  423.         responder->write_unselectable();
  424.     bcast = (ip_address *)get_local_address();
  425.     bcast->set_port(port);
  426.     
  427. //#ifdef TCPIP_DEBUG
  428.         *((unsigned char *)(&bcast->addr.sin_addr)+3) = 255;
  429.         bcast->store_string(s,256);
  430.         dprintf("Simulating broadcast to [%s]\n",s);
  431. //#endif
  432.  
  433.         *((unsigned char *)(&bcast->addr.sin_addr)+3) = 0;        
  434.     }
  435.  
  436.   if (responder)
  437.   {
  438.     int i;
  439.     
  440.     for (i=0; i<5; i++)
  441.     {
  442. #ifdef TCPIP_DEBUG
  443.             bcast->store_string(s,256);
  444.             dprintf("\r[%s]",s);
  445. #endif
  446.         int found = 0;
  447.         
  448.         for (p_request p = servers.begin(); !found && p!=servers.end(); ++p)
  449.             if ( *((*p)->addr) == *bcast )
  450.                 found = 1;
  451.         for (p_request q = returned.begin(); !found && q!=returned.end(); ++q)
  452.             if ( *((*q)->addr) == *bcast )
  453.                 found = 1;
  454.                 
  455.             if (!found) {
  456.                 responder->write((void*)notify_signature,
  457.                                                  strlen(notify_signature),bcast);
  458.                 select(0);
  459.             }
  460.         *((unsigned char *)(&bcast->addr.sin_addr)+3) += 1;
  461.     
  462.         select(0);
  463.         
  464.         if (!servers.empty())
  465.             break;
  466.         }
  467.   }
  468.   
  469.   if (servers.empty())
  470.     return 0;
  471.  
  472.   servers.move_next(servers.begin_prev(), returned.begin_prev());
  473.     ip_address *ret = (ip_address*)(*returned.begin())->addr->copy();
  474.     strcpy(name,(*returned.begin())->name);
  475.  
  476. #ifdef TCPIP_DEBUG
  477.     ret->store_string(s,256);
  478.     dprintf("Found [%s]\n",s);
  479. #endif
  480.  
  481.   return ret;
  482. }
  483. //}}}///////////////////////////////////
  484.  
  485. void tcpip_protocol::reset_find_list()
  486. //{{{
  487. {
  488.     p_request p;
  489.     
  490.     for (p=servers.begin(); p!=servers.end(); ++p)
  491.         delete (*p)->addr;
  492.     for (p=returned.begin(); p!=returned.end(); ++p)
  493.         delete (*p)->addr;
  494.         
  495.   servers.erase_all();
  496.   returned.erase_all();
  497. }
  498. //}}}///////////////////////////////////
  499.  
  500. int tcpip_protocol::handle_responder()
  501. //{{{
  502. {
  503.   if (!responder)
  504.     return 0;
  505.     
  506.   if (responder->ready_to_read())
  507.   {
  508.     char buf[513];
  509.     int len;
  510.     // got a notification response
  511.     ip_address *addr;
  512.  
  513. #ifdef TCPIP_DEBUG
  514.         dprintf("Responder: ");
  515. #endif
  516.  
  517.     len = responder->read(buf, 512, (net_address**)&addr);
  518.  
  519. #ifdef TCPIP_DEBUG
  520.         if (len>0) {
  521.             buf[len] = 0;
  522.             dprintf("[%s] ",buf);
  523.         }
  524. #endif
  525.     if (addr && len>0)
  526.     {
  527.         buf[len] = 0;
  528.       buf[4] = 0;                                                // ack! hard coded numbers for now
  529.       if (strcmp(buf,notify_response)==0)
  530.       {
  531.           int found=0;
  532.           for (p_request p = servers.begin(); !found && p!=servers.end(); ++p)
  533.               if ( *((*p)->addr) == *addr)
  534.                    found = 1;
  535.             for (p_request q = returned.begin(); !found && q!=returned.end(); ++q)
  536.                 if ( *((*q)->addr) == *addr )
  537.                     found = 1;
  538.                    
  539.           if (!found)
  540.           {
  541.                     char s[256];
  542.                     RequestItem *r = new RequestItem;
  543.                     r->addr = addr;
  544.                     strcpy(r->name,buf+5);                    // ack hard coded numbers for now
  545.             servers.insert(r);
  546. #ifdef TCPIP_DEBUG
  547.                     addr->store_string(s,256);
  548.                     dprintf("accepted %s",s);
  549. #endif
  550.                 }
  551.             }
  552.       else {
  553.         delete addr;
  554.             }
  555.     }
  556. #ifdef TCPIP_DEBUG
  557.     dprintf("\n");
  558. #endif
  559.  
  560.     return 1;
  561.   }
  562.   if (responder->error())
  563.   {
  564.     dprintf("Error on responder socket!\n");
  565.     return 1;
  566.   }
  567.  
  568.   return 0;
  569. }
  570. //}}}///////////////////////////////////
  571.  
  572. tcpip_protocol::tcpip_protocol()
  573. //{{{
  574.   : notifier(0), notify_len(0), responder(0)
  575. {
  576. #ifdef __MAC__
  577.   GUSISetup(GUSIwithSIOUXSockets);
  578.   GUSISetup(GUSIwithPPCSockets);
  579. #endif  
  580.   FD_ZERO(&master_set);  
  581.   FD_ZERO(&master_write_set);  
  582.   FD_ZERO(&read_set);
  583.   FD_ZERO(&exception_set);
  584.   FD_ZERO(&write_set);
  585. }
  586. //}}}///////////////////////////////////
  587.  
  588. int tcpip_protocol::select(int block)
  589. //{{{
  590. {
  591.   int ret;
  592.   
  593.   memcpy(&read_set,&master_set,sizeof(master_set));
  594.   memcpy(&exception_set,&master_set,sizeof(master_set));
  595.   memcpy(&write_set,&master_write_set,sizeof(master_set));
  596.   if (block)
  597.   {
  598.     ret = 0;
  599.     while (ret == 0) {
  600.       // get number of sockets ready from system call
  601.       ret = ::select(FD_SETSIZE,&read_set,&write_set,&exception_set,NULL);
  602.  
  603.       // remove notifier & responder events from the count of sockets selected
  604.       if (handle_notification())
  605.         ret--;
  606.       if (handle_responder())
  607.         ret--;
  608.     }
  609.   }
  610.   else
  611.   {
  612.     timeval tv={0,0};
  613.     // get number of sockets ready from system call
  614.     ret = ::select(FD_SETSIZE,&read_set,&write_set,&exception_set,&tv);
  615.  
  616.     // remove notifier & responder events from the count of sockets selected
  617.     if (handle_notification())
  618.       ret--;
  619.     if (handle_responder())
  620.       ret--;
  621.   }
  622.   return ret;
  623. }
  624. //}}}///////////////////////////////////
  625.  
  626. void tcpip_protocol::cleanup()
  627. //{{{
  628. {
  629.     if (notifier)
  630.         end_notify();
  631.         
  632.     reset_find_list();
  633.         
  634.     if (responder) {
  635.         delete responder;
  636.         delete bcast;
  637.         responder = 0;
  638.     }
  639. }
  640. //}}}///////////////////////////////////
  641.  
  642. //{{{ Revision Log
  643. /*//////////////////////////////////////////////////////////////////////
  644. $Log$
  645. //////////////////////////////////////////////////////////////////////*/
  646. //}}}
  647.  
  648. //{{{ Emacs Locals
  649. // Local Variables:
  650. // folded-file: t
  651. // End:
  652. //}}}
  653.  
  654.